package com.dsunsoft.rtu.service.impl;

import com.dsunsoft.rtu.common.util.CommonUtils;
import com.dsunsoft.rtu.common.vo.NgalainMenuTreeVO;
import com.dsunsoft.rtu.core.base.BaseServiceImpl;
import com.dsunsoft.rtu.dao.SysRoleMapper;
import com.dsunsoft.rtu.dao.SysUserMapper;
import com.dsunsoft.rtu.dto.SysUserDto;
import com.dsunsoft.rtu.dto.SysUserMenuDto;
import com.dsunsoft.rtu.entity.SysMenu;
import com.dsunsoft.rtu.entity.SysRole;
import com.dsunsoft.rtu.entity.SysUser;
import com.dsunsoft.rtu.entity.SysUserRole;
import com.dsunsoft.rtu.query.SysUserQuery;
import com.dsunsoft.rtu.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser, SysUserQuery> implements SysUserService {

    @Autowired
    private SysRoleMapper roleMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean save(SysUserDto sysUser) {
        int count = 0;
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        if (!StringUtils.hasText(sysUser.getId())) {
            sysUser.setId(CommonUtils.getUuid());
            sysUser.setPassword(passwordEncoder.encode(sysUser.getNewPassword()));
            count += mapper.insert(sysUser);
        } else {
            // 如果新密码为空，则不更换密码
            if (StringUtils.hasText(sysUser.getNewPassword())) {
                sysUser.setPassword(passwordEncoder.encode(sysUser.getNewPassword()));
            }
            count += mapper.update(sysUser);
            // 更新用户与角色关联
            mapper.deleteUserRole(sysUser);
        }
        // 设置用户角色
        List<SysUserRole> roleList = new ArrayList<>();
        for (String roleId : sysUser.getRoleIds()) {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setRoleId(roleId);
            sysUserRole.setUserId(sysUser.getId());
            sysUserRole.setUserRoleId(CommonUtils.getUuid());
            roleList.add(sysUserRole);
        }
        count += mapper.insertUserRole(roleList);
        return count > 0;
    }

    @Override
    public boolean checkLoginName(String oldLoginName, String loginName) {
        if (loginName != null && loginName.equals(oldLoginName)) {
            return true;
        } else if (loginName != null && mapper.selectByName(loginName) == null) {
            return true;
        }
        return false;
    }

    @Override
    public SysUserMenuDto getUserMenu(String userId) {
        SysUserMenuDto menuDto = new SysUserMenuDto();
        SysUser user = mapper.selectById(userId);
        menuDto.setUserId(user.getId());
        menuDto.setLoginName(user.getLoginName());
        menuDto.setName(user.getName());
        // 获取角色
        List<SysRole> roleList = roleMapper.selectRoleByUserId(userId);
        if (!CollectionUtils.isEmpty(roleList)) {
            List<String> roleIds = roleList.stream().map(SysRole::getRoleId).collect(Collectors.toList());
            List<String> roleCodes = roleList.stream().map(SysRole::getRoleCode).collect(Collectors.toList());
            menuDto.setRoleCodes(roleCodes);
            // 获取菜单
            List<SysMenu> menuList = roleMapper.selectMenuByRoleIds(roleIds);
            if (menuList != null) {
                List<SysMenu> buttonPermissionList = menuList.stream().filter(p -> p.getMenuType().equals(2)).collect(Collectors.toList());
                menuList = menuList.stream().filter(p -> p.getMenuType().equals(1)).collect(Collectors.toList());
                Map<String, NgalainMenuTreeVO> parentTreeKey = new HashMap<String, NgalainMenuTreeVO>();
                ArrayList<NgalainMenuTreeVO> treeList = new ArrayList<NgalainMenuTreeVO>();
                for (SysMenu menu : menuList) {
                    NgalainMenuTreeVO tree = getNgAlainTree(menu);
                    NgalainMenuTreeVO parentTree = (NgalainMenuTreeVO) parentTreeKey.get(menu.getPid());
                    if (parentTree == null) {
                        addTreeToList(treeList, tree);
                        parentTreeKey.put(tree.getMenuId(), tree);
                    } else {
                        if (parentTree.getChildren() == null) {
                            ArrayList<NgalainMenuTreeVO> items = new ArrayList<NgalainMenuTreeVO>();
                            items.add(tree);
                            parentTree.setChildren(items);
                        } else {
                            parentTree.getChildren().add(tree);
                        }
                        parentTreeKey.put(tree.getMenuId(), tree);
                    }
                }
                NgalainMenuTreeVO rootTree = new NgalainMenuTreeVO();
                rootTree.setText("主导航");
                rootTree.setI18n("menu.main");
                rootTree.setGroup(false);
                rootTree.setHideInBreadcrumb(true);
                rootTree.setLink("/dashboard/workplace");
                rootTree.setChildren(treeList);
                rootTree.setIcon("anticon anticon-dashboard");
                ArrayList<NgalainMenuTreeVO> rootTreeList = new ArrayList<NgalainMenuTreeVO>();
                rootTreeList.add(rootTree);
                menuDto.setMenuTreeList(rootTreeList);
                menuDto.setButtonPermissionList(buttonPermissionList);
            }
        }
        return menuDto;
    }

    private void addTreeToList(ArrayList<NgalainMenuTreeVO> treeList, NgalainMenuTreeVO tree) {
        boolean isHave = false;
        for (NgalainMenuTreeVO t : treeList) {
            if (t.getMenuId().equals(tree.getMenuId())) {
                isHave = true;
            }
        }
        if (!isHave) {
            treeList.add(tree);
        }
    }

    private NgalainMenuTreeVO getNgAlainTree(SysMenu detail) {
        NgalainMenuTreeVO tree = new NgalainMenuTreeVO();
        tree.setText(detail.getMenuName());
        tree.setRemarks(detail.getRemarks());
        // tree.setI18n("menu." + detail.getMenuId());
        tree.setIcon(detail.getIcon());
        tree.setMenuId(detail.getMenuId());
        tree.setLink(detail.getPath());
        if (tree.getLink() == null) {
            tree.setReuse(true);
        } else if ("".equals(tree.getLink())
                || "/".equals(tree.getLink())
                || "/home".equals(tree.getLink())
        ) {
            tree.setReuse(true);
        }
        return tree;
    }
}
